Skip to content

trial countdown#2030

Open
ignaciojimenezr wants to merge 1 commit intomainfrom
countdowN
Open

trial countdown#2030
ignaciojimenezr wants to merge 1 commit intomainfrom
countdowN

Conversation

@ignaciojimenezr
Copy link
Copy Markdown
Collaborator

@ignaciojimenezr ignaciojimenezr commented May 6, 2026

Sidebar trial countdown

  • Adds a compact trial countdown row to the sidebar footer, driven off trialEndsAt (label + remaining days/hours/minutes)
  • Live-ticks (every minute, every second in the final hour); whole row is clickable and routes to the billing page
  • Only renders when trialStatus === "active" and the billingUiEnabled flag is on
image

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label May 6, 2026
@chelojimenez
Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@dosubot dosubot Bot added the enhancement New feature or request label May 6, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 6, 2026

Internal preview

Preview URL: https://mcp-inspector-pr-2030.up.railway.app
Deployed commit: afe7daa
PR head commit: b3226ff
Backend target: staging fallback.
Health: ❌ Convex unreachable — see upsert-preview job logs (staging may need convex deploy)
Access is employee-only in non-production environments.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

Walkthrough

This change introduces trial countdown functionality to the MCP sidebar. A new SidebarTrialCountdown component was created to display remaining trial time with a progress bar and formatted countdown text. The sidebar component was updated to import and conditionally render this countdown widget in the footer when an invite CTA is displayed and an active trial with an end date exists. The billing status hook was wired to track trial state and provide navigation to the billing page on upgrade. A test mock was extended to support the new query usage.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
mcpjam-inspector/client/src/components/sidebar/__tests__/sidebar-invite-cta.test.tsx (1)

11-14: ⚡ Quick win

Please add one active-trial test path in this suite.

Line 13 hardcodes useQuery to undefined, so the new SidebarTrialCountdown branch is never validated here. A single case mocking an active trial payload (end date + status) and asserting countdown render plus upgrade navigation would close that gap.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@mcpjam-inspector/client/src/components/sidebar/__tests__/sidebar-invite-cta.test.tsx`
around lines 11 - 14, Add one test case to the sidebar-invite-cta.test.tsx suite
that covers the active-trial branch by mocking useQuery to return an active
trial payload (include a future end date and status "active") instead of
undefined; in that test render the SidebarTrialCountdown (via the existing
component tree in the test), assert the countdown text or timer is present, and
assert the upgrade navigation element (button/link) is rendered and triggers the
expected navigation callback; reuse the existing mockUseConvexAuth setup and
only override useQuery for this single test so other tests remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@mcpjam-inspector/client/src/components/sidebar/sidebar-trial-countdown.tsx`:
- Around line 18-23: In the sidebar-trial-countdown component useEffect, the
interval is computed once from trialEndsAt so the tick cadence never tightens
when remaining time drops below an hour; change the logic to schedule/reschedule
on each tick (for example replace the fixed setInterval with a self-rescheduling
timer or clear-and-set a new timer inside the callback) so you compute remaining
= trialEndsAt - Date.now() on every tick and choose 1000ms or 60000ms
accordingly; ensure you still call setNow(Date.now()) each tick and properly
clear the timeout/interval in the cleanup to avoid leaks (refer to useEffect,
setNow, the interval id variable).

---

Nitpick comments:
In
`@mcpjam-inspector/client/src/components/sidebar/__tests__/sidebar-invite-cta.test.tsx`:
- Around line 11-14: Add one test case to the sidebar-invite-cta.test.tsx suite
that covers the active-trial branch by mocking useQuery to return an active
trial payload (include a future end date and status "active") instead of
undefined; in that test render the SidebarTrialCountdown (via the existing
component tree in the test), assert the countdown text or timer is present, and
assert the upgrade navigation element (button/link) is rendered and triggers the
expected navigation callback; reuse the existing mockUseConvexAuth setup and
only override useQuery for this single test so other tests remain unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f992eec3-2040-4247-ba11-074039373798

📥 Commits

Reviewing files that changed from the base of the PR and between 78ebf08 and b3226ff.

📒 Files selected for processing (3)
  • mcpjam-inspector/client/src/components/mcp-sidebar.tsx
  • mcpjam-inspector/client/src/components/sidebar/__tests__/sidebar-invite-cta.test.tsx
  • mcpjam-inspector/client/src/components/sidebar/sidebar-trial-countdown.tsx

Comment on lines +18 to +23
useEffect(() => {
const remaining = trialEndsAt - Date.now();
const interval = remaining < 60 * 60 * 1000 ? 1_000 : 60_000;
const id = window.setInterval(() => setNow(Date.now()), interval);
return () => window.clearInterval(id);
}, [trialEndsAt]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Countdown cadence never tightens in the final hour.

Line 20 computes the interval only once per trialEndsAt, so a trial that starts with >1h left keeps a 60s tick even when the UI shows seconds. Re-schedule based on current remaining time each tick.

Suggested fix
-  useEffect(() => {
-    const remaining = trialEndsAt - Date.now();
-    const interval = remaining < 60 * 60 * 1000 ? 1_000 : 60_000;
-    const id = window.setInterval(() => setNow(Date.now()), interval);
-    return () => window.clearInterval(id);
-  }, [trialEndsAt]);
+  useEffect(() => {
+    const remaining = trialEndsAt - now;
+    if (remaining <= 0) return;
+
+    const delay = remaining < 60 * 60 * 1000 ? 1_000 : 60_000;
+    const id = window.setTimeout(() => setNow(Date.now()), delay);
+    return () => window.clearTimeout(id);
+  }, [now, trialEndsAt]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
useEffect(() => {
const remaining = trialEndsAt - Date.now();
const interval = remaining < 60 * 60 * 1000 ? 1_000 : 60_000;
const id = window.setInterval(() => setNow(Date.now()), interval);
return () => window.clearInterval(id);
}, [trialEndsAt]);
useEffect(() => {
const remaining = trialEndsAt - now;
if (remaining <= 0) return;
const delay = remaining < 60 * 60 * 1000 ? 1_000 : 60_000;
const id = window.setTimeout(() => setNow(Date.now()), delay);
return () => window.clearTimeout(id);
}, [now, trialEndsAt]);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@mcpjam-inspector/client/src/components/sidebar/sidebar-trial-countdown.tsx`
around lines 18 - 23, In the sidebar-trial-countdown component useEffect, the
interval is computed once from trialEndsAt so the tick cadence never tightens
when remaining time drops below an hour; change the logic to schedule/reschedule
on each tick (for example replace the fixed setInterval with a self-rescheduling
timer or clear-and-set a new timer inside the callback) so you compute remaining
= trialEndsAt - Date.now() on every tick and choose 1000ms or 60000ms
accordingly; ensure you still call setNow(Date.now()) each tick and properly
clear the timeout/interval in the cleanup to avoid leaks (refer to useEffect,
setNow, the interval id variable).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants